summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/audio/audin_u.cpp5
-rw-r--r--src/core/hle/service/audio/audout_u.cpp10
-rw-r--r--src/core/hle/service/audio/audren_u.cpp15
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp10
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp9
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h10
8 files changed, 52 insertions, 14 deletions
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index 26dec7147..053e8f9dd 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -203,8 +203,9 @@ private:
};
AudInU::AudInU(Core::System& system_)
- : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"},
- impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} {
+ : ServiceFramework{system_, "audin:u", ServiceThreadType::CreateNew},
+ service_context{system_, "AudInU"}, impl{std::make_unique<AudioCore::AudioIn::Manager>(
+ system_)} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &AudInU::ListAudioIns, "ListAudioIns"},
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 991e30ba1..29751f075 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -26,8 +26,9 @@ public:
explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
size_t session_id, const std::string& device_name,
const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id)
- : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
- event{service_context.CreateEvent("AudioOutEvent")},
+ : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew},
+ service_context{system_, "IAudioOut"}, event{service_context.CreateEvent(
+ "AudioOutEvent")},
impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
// clang-format off
@@ -220,8 +221,9 @@ private:
};
AudOutU::AudOutU(Core::System& system_)
- : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"},
- impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} {
+ : ServiceFramework{system_, "audout:u", ServiceThreadType::CreateNew},
+ service_context{system_, "AudOutU"}, impl{std::make_unique<AudioCore::AudioOut::Manager>(
+ system_)} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &AudOutU::ListAudioOuts, "ListAudioOuts"},
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index ead16c321..3a1c231b6 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -35,9 +35,10 @@ public:
AudioCore::AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
u32 process_handle, u64 applet_resource_user_id, s32 session_id)
- : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"},
- rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_},
- impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {
+ : ServiceFramework{system_, "IAudioRenderer", ServiceThreadType::CreateNew},
+ service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent(
+ "IAudioRendererEvent")},
+ manager{manager_}, impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
@@ -242,8 +243,10 @@ class IAudioDevice final : public ServiceFramework<IAudioDevice> {
public:
explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,
u32 device_num)
- : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"},
- impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)},
+ : ServiceFramework{system_, "IAudioDevice", ServiceThreadType::CreateNew},
+ service_context{system_, "IAudioDevice"}, impl{std::make_unique<AudioDevice>(
+ system_, applet_resource_user_id,
+ revision)},
event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} {
static const FunctionInfo functions[] = {
{0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
@@ -418,7 +421,7 @@ private:
};
AudRenU::AudRenU(Core::System& system_)
- : ServiceFramework{system_, "audren:u"},
+ : ServiceFramework{system_, "audren:u", ServiceThreadType::CreateNew},
service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} {
// clang-format off
static const FunctionInfo functions[] = {
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 558b8db56..84d36fea6 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -285,6 +285,9 @@ void BufferCacheRuntime::BindQuadArrayIndexBuffer(u32 first, u32 count) {
void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size,
u32 stride) {
+ if (index >= device.GetMaxVertexInputBindings()) {
+ return;
+ }
if (device.IsExtExtendedDynamicStateSupported()) {
scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) {
const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0;
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 006128638..4b10fe7bc 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -529,7 +529,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors;
static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes;
if (key.state.dynamic_vertex_input) {
- for (size_t index = 0; index < key.state.attributes.size(); ++index) {
+ const size_t num_vertex_arrays = std::min(
+ key.state.attributes.size(), static_cast<size_t>(device.GetMaxVertexInputBindings()));
+ for (size_t index = 0; index < num_vertex_arrays; ++index) {
const u32 type = key.state.DynamicAttributeType(index);
if (!stage_infos[0].loads.Generic(index) || type == 0) {
continue;
@@ -551,7 +553,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
});
}
} else {
- for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
+ const size_t num_vertex_arrays = std::min(
+ Maxwell::NumVertexArrays, static_cast<size_t>(device.GetMaxVertexInputBindings()));
+ for (size_t index = 0; index < num_vertex_arrays; ++index) {
const bool instanced = key.state.binding_divisors[index] != 0;
const auto rate =
instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
@@ -580,6 +584,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
});
}
}
+ ASSERT(vertex_attributes.size() <= device.GetMaxVertexInputAttributes());
+
VkPipelineVertexInputStateCreateInfo vertex_input_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.pNext = nullptr,
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 81f5f3e11..86fdde014 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -341,6 +341,15 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.support_snorm_render_buffer = true,
.support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(),
};
+
+ if (device.GetMaxVertexInputAttributes() < Maxwell::NumVertexAttributes) {
+ LOG_WARNING(Render_Vulkan, "maxVertexInputAttributes is too low: {} < {}",
+ device.GetMaxVertexInputAttributes(), Maxwell::NumVertexAttributes);
+ }
+ if (device.GetMaxVertexInputBindings() < Maxwell::NumVertexArrays) {
+ LOG_WARNING(Render_Vulkan, "maxVertexInputBindings is too low: {} < {}",
+ device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays);
+ }
}
PipelineCache::~PipelineCache() = default;
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 6a2ad4b1d..67540cb80 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -1380,6 +1380,10 @@ void Device::SetupFeatures() {
is_shader_storage_image_multisample = features.shaderStorageImageMultisample;
is_blit_depth_stencil_supported = TestDepthStencilBlits();
is_optimal_astc_supported = IsOptimalAstcSupported(features);
+
+ const VkPhysicalDeviceLimits& limits{properties.limits};
+ max_vertex_input_attributes = limits.maxVertexInputAttributes;
+ max_vertex_input_bindings = limits.maxVertexInputBindings;
}
void Device::SetupProperties() {
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index db802437c..391b7604c 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -368,6 +368,14 @@ public:
return must_emulate_bgr565;
}
+ u32 GetMaxVertexInputAttributes() const {
+ return max_vertex_input_attributes;
+ }
+
+ u32 GetMaxVertexInputBindings() const {
+ return max_vertex_input_bindings;
+ }
+
private:
/// Checks if the physical device is suitable.
void CheckSuitability(bool requires_swapchain) const;
@@ -467,6 +475,8 @@ private:
bool supports_d24_depth{}; ///< Supports D24 depth buffers.
bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting.
bool must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format.
+ u32 max_vertex_input_attributes{}; ///< Max vertex input attributes in pipeline
+ u32 max_vertex_input_bindings{}; ///< Max vertex input buffers in pipeline
// Telemetry parameters
std::string vendor_name; ///< Device's driver name.